package com.reformer.commons.utils;

import com.reformer.commons.constant.SignType;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * RSA，DSA签名验签工具类
 */
public class SignatureUtil {

    public static String sign(SignType signType, String text, String privateKeyData, String charset)
            throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException, UnsupportedEncodingException {
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyData));
        PrivateKey privateKey = KeyFactory.getInstance(signType.getName()).generatePrivate(keySpec);
        return sign(signType, text, privateKey, charset);
    }

    private static String sign(SignType signType, String text, PrivateKey privateKey, String charset)
            throws NoSuchAlgorithmException, SignatureException, InvalidKeyException, UnsupportedEncodingException {
        Signature signature = Signature.getInstance(signType.getSigAlg());
        signature.initSign(privateKey);
        signature.update(text.getBytes(charset));
        return Base64.encode(signature.sign());
    }

    public static boolean verify(SignType signType, String text, String publicKeyData, String sign, String charset)
            throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException, UnsupportedEncodingException {
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(publicKeyData));
        PublicKey publicKey = KeyFactory.getInstance(signType.getName()).generatePublic(keySpec);
        return verify(signType, text, publicKey, sign, charset);
    }

    private static boolean verify(SignType signType, String text, PublicKey publicKey, String sign, String charset)
            throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, UnsupportedEncodingException {
        Signature signatureChecker = Signature.getInstance(signType.getSigAlg());
        signatureChecker.initVerify(publicKey);
        signatureChecker.update(text.getBytes(charset));
        return signatureChecker.verify(Base64.decode(sign));
    }

    public static boolean verify(SignType signType, String text, Certificate cert, String sign)
            throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        Signature sig = Signature.getInstance(signType.getSigAlg());
        sig.initVerify(cert);
        sig.update(text.getBytes());
        return sig.verify(Base64.decode(sign));
    }

//    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, UnsupportedEncodingException, InvalidKeyException, SignatureException {
//        String priKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANDPSJCKLbUSvzyYegxZKz6IjktHe85ksSP9DxqxlPhmiX+Trf1KQtWU4l745VlPgpJiNlyN3QyX09/Tgx7uyVJcXKFm1jwUYrp+6li1OCna0R/3pW1LzbHY+6bl+UHJIan4pWXElyju7KNQWZmUU11xObD/hSdDd3mcvBPUGkP9AgMBAAECgYBtq4EMUVbCVM9WTytDEw5QcL5zsV7IP0B+i2oEdiKs+IXdGL54WymRLfpbMVScPNNyeNzebbAc7h1c4KVseLQJdv+Dvvacm1SC7xI2zS71NpMQdmX7MQL/f1ie4gCWTs7CZPS0yNs2sk4CuK8PhcqXGio5pMDG8t7ymeW+tKERIQJBAP4dJcjJ5GhdMigA1tz/xMa7GgWikTKil1/EoLr32NmAwcYVA+Js4WllSlaqncO63PX/mjdvW3EF1401RJ+R7NUCQQDSXA0xIijJmzyGzMkETZaXmRz3xZRMaPxOH0o2/5fH4gyLurH4xk2FCFcaeAcbFGLYb7iO7wNFF0ftzZ+Bw26JAkBxELcHKA2hAhaXBgiUPJlpc0aYy0Sfqwh/bBW4Gx85Z7jQUflwfdGt+4ugFDouJK68JgaQM9QT7e2CvvjRpzQhAkBOAD4QAveW0g4eed7rzo1Rhz/bjBLSRnePzEBrpli0kFhQk5icg4OJGa+aq/kOjH+ee8a2kV/oBZrxTbagmkPpAkEAo91GpnWJekwxIDMGqSMQ5rIIgbHptKGzTzZgRfDM997q5obBrq497yBbMkwH6N674t3rmqxlxUGqTefkWHozHg==";
//        String pubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQz0iQii21Er88mHoMWSs+iI5LR3vOZLEj/Q8asZT4Zol/k639SkLVlOJe+OVZT4KSYjZcjd0Ml9Pf04Me7slSXFyhZtY8FGK6fupYtTgp2tEf96VtS82x2Pum5flBySGp+KVlxJco7uyjUFmZlFNdcTmw/4UnQ3d5nLwT1BpD/QIDAQAB";
//        System.out.println(sign(SignType.RSA_SHA256,"hello",priKey, StandardCharsets.UTF_8.name()));
//    }
}